package com.norns.torque.network

import android.content.Context
import android.net.ConnectivityManager
import android.net.ConnectivityManager.NetworkCallback
import android.net.Network
import android.net.NetworkCapabilities
import com.norns.torque.utils.AppContext
import timber.log.Timber


object NetworkListenerHelper {

    private var networkCallback:MyNetworkCallback
    init {
        networkCallback=MyNetworkCallback()
    }
    /**
     * 注册网络状态的监听；
     */
    fun registerNetworkListener(context: Context) {
        val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as? ConnectivityManager
        if (connectivityManager == null) {
            Timber.e("registerNetworkListener#return#connectivityManager=$connectivityManager")
            return
        }
        connectivityManager.registerDefaultNetworkCallback(networkCallback)
    }
    /**
     * 取消网络状态的监听；
     */
    fun unregisterNetworkCallback(context: Context) {
        val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as? ConnectivityManager
        if (connectivityManager == null) {
            Timber.e("registerNetworkListener#return#connectivityManager=$connectivityManager")
            return
        }
        connectivityManager.unregisterNetworkCallback(networkCallback)
    }
    /**
     * 添加回调的监听者；
     */
    fun addListener(listener: NetworkConnectedListener) {
        networkCallback.addListener(listener)

    }
    /**
     * 移除某个回调实例；
     *
     * @param listener
     */
    fun removeListener(listener: NetworkConnectedListener?) {
        networkCallback.removeListener(listener)
    }

    interface NetworkConnectedListener {
        /**
         * @param isConnected
         * @param networkStatus
         */
        fun onNetworkConnected(
            isConnected: Boolean,
            networkStatus: NetworkStatus
        )
    }

    private class MyNetworkCallback : NetworkCallback() {
        private var mListenerList: ArrayList<NetworkConnectedListener> = ArrayList()
        /**
         * 通知所有接收者；
         *
         * @param isConnected
         * @param networkStatus
         */
        private fun notifyAllListeners(
            isConnected: Boolean,
            networkStatus: NetworkStatus
        ) {
            for (listener in mListenerList) {
                listener.onNetworkConnected(isConnected, networkStatus)
            }
        }
        /**
         * 添加回调的监听者；
         */
        fun addListener(listener: NetworkConnectedListener) {
            // 防止重复添加；
            if (!mListenerList.contains(listener)) {
                mListenerList.add(listener)
            }
        }
        /**
         * 移除某个回调实例；
         *
         * @param listener
         */
        fun removeListener(listener: NetworkConnectedListener?) {
            if (listener != null && mListenerList.isNotEmpty()) {
                mListenerList.remove(listener)
            }
        }

        //当用户与网络连接（或断开连接）（可以是WiFi或蜂窝网络）时，这两个功能均作为默认回调;
        override fun onAvailable(network: Network) {
            super.onAvailable(network)
            Timber.d("onAvailable#network=$network")
            // 需要同步获取一次网络状态；
            val netWorkState = NetworkUtils.getNetWorkState(AppContext.context)
            Timber.d("onAvailable#netWorkState=$netWorkState")
            //
            notifyAllListeners(true, netWorkState)
        }

        override fun onLost(network: Network) {
            super.onLost(network)
            Timber.d( "onLost#network=$network")
            // 需要同步获取一次网络状态；
            val netWorkState = NetworkUtils.getNetWorkState(AppContext.context)
            Timber.d("onLost#netWorkState=$netWorkState")
            //
            notifyAllListeners(false, netWorkState)
        }

        override fun onCapabilitiesChanged(
            network: Network,
            networkCapabilities: NetworkCapabilities
        ) {
            super.onCapabilitiesChanged(network, networkCapabilities)
            Timber.d("onCapabilitiesChanged#network=$network")
            //            LogUtils.d(TAG, "onCapabilitiesChanged#network=" + network + ", networkCapabilities=" + networkCapabilities);
            // 表示能够和互联网通信（这个为true表示能够上网）
            if (networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)) {
                when {
                    networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> {
                        Timber.d( "onCapabilitiesChanged#网络类型为wifi")
                    }
                    networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> {
                        Timber.d("onCapabilitiesChanged#蜂窝网络")
                    }
                    else -> {
                        Timber.d( "onCapabilitiesChanged#其他网络")
                    }
                }
            }
        }
    }
}